package impl

import (
	"encoding/json"
	"fmt"
	"github.com/gin-gonic/gin"
	"github.com/spf13/viper"
	"io"
	"log"
	"net/http"
	"nodemessage.com/hook-for-gitee/utils"
	"strings"
)

type GiteeHookService struct {
}

func (receiver *GiteeHookService) Handler(c *gin.Context) {
	var giteeHookKey = viper.GetString(c.Param("uuid") + ".hookKey")
	var command = viper.GetString(c.Param("uuid") + ".command")
	if giteeHookKey == "" {
		log.Println("未配置路径:", c.Param("uuid"))
		c.JSON(http.StatusInternalServerError, map[string]interface{}{
			"status": "notConf",
		})
		return
	}
	hookKey := c.Request.Header.Get("X-Gitee-Token")
	log.Println("hookKey:", hookKey)
	if compare := strings.Compare(hookKey, giteeHookKey); compare != 0 {
		log.Println(c.Param("uuid"), " ,hookKey 不正确")
		c.JSON(http.StatusOK, map[string]interface{}{
			"status": "unauth",
		})
		return
	}

	if bytes, err := io.ReadAll(c.Request.Body); err != nil {
		log.Println(err)
	} else {
		var jsonObj map[string]interface{}
		if err := json.Unmarshal(bytes, &jsonObj); err != nil {
			log.Println(err)
		} else {
			handler(c, jsonObj, command)
			log.Println("本次hook成功")
			return
		}
	}
	c.JSON(http.StatusOK, map[string]interface{}{
		"status": "ok",
	})
}

/* 处理push */
func handler(c *gin.Context, jsonObj map[string]interface{}, command string) {
	log.Println(jsonObj)

	/* 是否在可执行分支内 */
	uuid := c.Param("uuid")
	refStr := jsonObj["ref"].(string)
	refs := strings.Split(refStr, "/")
	if !utils.IsContain(viper.GetStringSlice(uuid+".branchs"), refs[2]) {
		log.Println(refs[2], "分支不进行操作")
		c.JSON(http.StatusOK, map[string]interface{}{
			"status": "ok",
		})
		return
	}

	/* 获取git地址 */
	pro, _ := jsonObj["project"].(map[string]interface{})
	var cloneUrl any
	protocol := viper.GetString(uuid + ".protocol")
	if protocol == "http" {
		cloneUrl = pro["git_http_url"]
	} else if protocol == "ssh" {
		cloneUrl = pro["git_ssh_url"]
	} else {
		log.Println("配置文件属性 " + uuid + ".protocol 配置错误. (http | ssh)")
		return
	}

	log.Println("git_http_url:", cloneUrl)
	/* 项目目录是否存在 */
	next := true
	if gitHttpUrlStr, gitUtlOk := cloneUrl.(string); gitUtlOk && utils.FileExist(pro["path"]) {
		log.Println("pull..")
		next = utils.RunCommand(fmt.Sprint(pro["path"]), "git", "pull")
	} else {
		log.Println("clone..")
		next = utils.RunCommand("./", "git", "clone", gitHttpUrlStr)
	}
	if !next {
		log.Println("项目拉取异常,退出")
		return
	}
	log.Println("项目拉取成功,开始执行...")
	/* 停止项目 */
	next = utils.RunScript("", viper.GetString(uuid+".closeServer"))
	if !next {
		log.Println("项目停止执行异常,退出")
		return
	}
	/* 运行项目 */
	next = utils.RunScript("", command)
	if !next {
		log.Println("项目启动异常,退出")
		return
	}
	/* 返回状态 */
	c.JSON(http.StatusOK, map[string]interface{}{
		"status": "ok",
	})
}
